import { Address, beginCell, toNano, fromNano, SendMode, } from '@ton/core';
import { MyStake } from '../wrappers/MyStake';
import { MyJettonMaster } from '../wrappers/MyJetton_MyJettonMaster';
import { MyJettonWallet } from '../wrappers/MyJetton_MyJettonWallet';
import { NetworkProvider } from '@ton/blueprint';

const tspa = "kQCrJ-ArHG3LoX_b9Wz7hLVSNeR0_Cz2hSUwashWDavq-r4P";
const tusdt = "kQCymv2MvB5Bb2Jd45D92HaUfmf06CBm-LJMFU7qjeSjX0V3";
const jetton_owner = "0QCjPTREUgXS0n1DxX3-clRKW6NIKp5zF8kxoGkYV2b229sN";
const tspa_wallet = "kQBhxrSFHGrvX1g5tubQbuePKvBBMtUMxnUMJRxBKjcTKUFd";
const jetton_to = "0QAKRJsZhhJGouqbtTpvXOjR9nB2ixjoCKHhmG2Nc1fcPT58";

const TRANSFER_OP = 0x4034a3c0;
const STAKE_OP = 0x6ec9dc65;

/**
 * 0QCjPTRE...V2b229sN -> kQBhxrSF...KjcTKUFd -> kQA-IcJl...CebwfjW6 -> kQDIZAFG...DqeYiPa8
 *     user wallet     ->  user jetton wallet -> stake jetton wallet -> stake contract
 *                                                                   -> 0QCjPTRE...V2b229sN
 *                                                                   -> sender wallet
 * kQDIZAFGFqETux9Z74Km_SIj4mVvqo7HfNjOwOTxDqeYiPa8
 * const stake = "EQDIZAFGFqETux9Z74Km_SIj4mVvqo7HfNjOwOTxDqeYiE02"
 */

const stake = "EQBHlEDiEeMjUWTXOcRJ6_MJ1CaPrO1_9eKnZZX5TuG0cwYC";

export async function run(provider: NetworkProvider) {
    // const contract_provider = provider.provider(Address.parse("Insert contract address"));
    // await deploy(provider);
    await amount(provider);
    // await forwardTransfer(provider);
}

export async function deploy(provider: NetworkProvider) {
    const owner_address = Address.parse(jetton_owner);
    const tspa_wallet_address = Address.parse(tspa_wallet);
    // const myStake = provider.open(await MyStake.fromInit(owner_address, tspa_wallet_address, 1000000n));
    const myStake = provider.open(await MyStake.fromInit());

    await myStake.send(
        provider.sender(),
        {
            value: toNano('0.05'),
            // sendMode: SendMode.PAY_GAS_SEPARATELY,
        },
        {
            $$type: 'Deploy',
            queryId: 0n,
        }
    );

    await provider.waitForDeploy(myStake.address);
    // run methods on `myStake`
}

async function initTransfer(provider: NetworkProvider) {
    const senderAddress = provider.sender()?.address;
    if (!senderAddress) {
        throw new Error('Sender address is undefined.');
    }
    const myJettonMaster = provider.open(
        MyJettonMaster.fromAddress(Address.parse(tspa)),
    );
    
    let jettonWalletAddress = await myJettonMaster.getGetWalletAddress(senderAddress);
    const srcWallet = provider.open(
        MyJettonWallet.fromAddress(jettonWalletAddress),
    );
    console.log('source address: '+senderAddress);
    
    const forwardTargetAddress = Address.parse(jetton_to);
    const targetAddress = Address.parse(stake);
    const targetJettonWalletAddress = await myJettonMaster.getGetWalletAddress(targetAddress);
    const targetJettonWallet = provider.open(
        MyJettonWallet.fromAddress(targetJettonWalletAddress),
    );
    console.log('target address: '+ targetJettonWalletAddress);
    
    /*
     * 第一次jetton转账之前,无法查询jetton余额.因为jetton wallet未部署.
    const walletDataBefore = await targetJettonWallet.getGetWalletData();
    const balanceBefore = walletDataBefore.balance;
    console.log('Current balance:' + fromNano(balanceBefore));
    */

    const transAmount = 0.01; // <-- ENTER THE AMOUNT OF JETTONS TO TRANSFER
    const nanoTransfer = toNano(transAmount);
    const comment = "init stake";
    const commentPayload = beginCell() 
        .storeBit(1)
        .storeRef(
            beginCell()
                .storeUint(0, 32)
                .storeStringTail(comment)
            .endCell()
        )
        .endCell()
        .beginParse()
        ;
    await srcWallet.send(
        provider.sender(),
        {
            value: toNano('0.05'),
        },
        {
            $$type: 'JettonTransfer',
            query_id: 101n,
            destination: targetAddress,
            response_destination: senderAddress,
            // 第一次激活jetton wallet
            amount: nanoTransfer,
            custom_payload: beginCell().endCell(),
            // 第一次转jetton时不带forward_ton_amount
            forward_ton_amount: 0n,
            // 第一次转jetton时带有备注的
            forward_payload: commentPayload,
        }
    );

    console.log(`Transfer ${transAmount} to ${targetAddress} and waiting 22s...`);
    await new Promise((resolve) => setTimeout(resolve, 22000));

    const walletDataAfter = await targetJettonWallet.getGetWalletData();
    const balanceAfter = walletDataAfter.balance;
    console.log('Current balance:' + fromNano(balanceAfter));
}

async function forwardTransfer(provider: NetworkProvider) {
    const senderAddress = provider.sender()?.address;
    if (!senderAddress) {
        throw new Error('Sender address is undefined.');
    }
    const myJettonMaster = provider.open(
        MyJettonMaster.fromAddress(Address.parse(tspa)),
    );
    
    let jettonWalletAddress = await myJettonMaster.getGetWalletAddress(senderAddress);
    const srcWallet = provider.open(
        MyJettonWallet.fromAddress(jettonWalletAddress),
    );
    console.log('source address: '+senderAddress);
    
    const forwardTargetAddress = Address.parse(jetton_to);
    const targetAddress = Address.parse(stake);
    const targetJettonWalletAddress = await myJettonMaster.getGetWalletAddress(targetAddress);
    const targetJettonWallet = provider.open(
        MyJettonWallet.fromAddress(targetJettonWalletAddress),
    );
    console.log('target address: '+ targetJettonWalletAddress);
    
    /*
     * 第一次jetton转账之前,无法查询jetton余额.因为jetton wallet未部署.
    const walletDataBefore = await targetJettonWallet.getGetWalletData();
    const balanceBefore = walletDataBefore.balance;
    console.log('Current balance:' + fromNano(balanceBefore));
    */

    const transAmount = 0.01; // <-- ENTER THE AMOUNT OF JETTONS TO TRANSFER
    const nanoTransfer = toNano(transAmount);
    const forwardNano = toNano('0.25');
    const forwardPayload = beginCell()
        .storeUint(1,1)
        .storeRef(
            beginCell()
            .storeUint(STAKE_OP, 32)
            .storeAddress(forwardTargetAddress)
            .endCell()
        ).endCell().beginParse();

    await srcWallet.send(
        provider.sender(),
        {
            value: toNano('0.3'),
            // sendMode: SendMode.PAY_GAS_SEPARATELY,
        },
        {
            $$type: 'JettonTransfer',
            query_id: 101n,
            destination: targetAddress,
            response_destination: senderAddress,
            amount: nanoTransfer,
            custom_payload: beginCell().endCell(),
            forward_ton_amount: forwardNano,
            forward_payload: forwardPayload,
        }
    );

    console.log(`Transfer ${transAmount} to ${targetAddress} and waiting 22s...`);
    await new Promise((resolve) => setTimeout(resolve, 22000));

    const walletDataAfter = await targetJettonWallet.getGetWalletData();
    const balanceAfter = walletDataAfter.balance;
    console.log('Current balance:' + fromNano(balanceAfter));
}

async function amount(provider: NetworkProvider) {
    const senderAddress = provider.sender()?.address;
    if (!senderAddress) {
        throw new Error('Sender address is undefined.');
    }
    const myStake = provider.open(
        MyStake.fromAddress(Address.parse(stake)),
    );
    
    let amount = await myStake.getAmount();
    console.log('amount:' + amount);
}